/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package helpdiabetesj2me;

import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Font;
import javax.microedition.rms.*;

/**
 *
 * @author Johan
 */
public class AddItem extends MyCanvas implements CommandListener {
    
 
     static final String[] str_gram = {"gram"};
     static final String[] str_stuk = {"stuk"};
     static final String[] str_terug = {"Terug"};
     static final String[] str_voegtoe = {"VoegToe"};
     static final String[] str_opslaan = {"Opslaan"};
     static final String[] str_bevat = {"bevat"};
     static final String[] str_amount_kh = {"gram koolhydraten."};
     static final String[] str_choseamnt= {"Kies hoeveelheid :"};
     static final String[] str_ontbijt= {"Ontbijt"};
     static final String[] str_middagmaal= {"Middagmaal"};
     static final String[] str_avondmaal= {"Avondmaal"};
     static final String[] str_unitsins = {"eenheden"};
     static final String[] str_total = {"Totaal"};
     static final String[] str_amount_ei = {"gram eiwit."};
     static final String[] str_amount_kcal = {"kilocaloriën."};
     static final String[] str_amount_vet= {"gram vet."};
     static final String[] str_andere_eenheid = {"Eenheid"};
     static final String[] str_of_carbs = {"koolhydraten."};
     static final String[] str_calc_percentage = {"% koolhydraten"};
     static final String[] str_warning_title = {"Berekening % koolhydraten."};
     static final String[] str_warning1 = {"Let op ! Deze berekening is enkel correct indien alle elementen 'gram' gebruiken als eenheid."};
     static final String[] str_warning2 = {"Het recept bevat"};
     static final String[] str_ok = {"Ok"};
     static final String[] str_modifyamnt= {"Wijzig hoeveelheid :"};
     static final String[] str_vieruurtje = {"Vieruurtje"};
     static final String[] str_calc_percentagelong = {"Percentage koolhydraten"};
     static final String[] str_porties_1 = {"porties van "};
     static final String[] str_porties_2 = {" gram koolhydraten"}; 

     // will contain the total amounts of eiwit, koolh, vet, kcal
    Float totkoolh;
    Float toteiwit;
    Float totvet;
    Float totkcal;
    //will contain the total amount of food - requested by Christophe J. to calculate percentage of carbs in a meal
    Float total;
    
    // used to pass the recid to commandAction
    int chosenrecordid;
    
    // added on 2/11/2008 to support multiple units per fooditem
    int unit_number_to_add; //value of the unitnumber that customer has chosen to add
    int max_nr_of_unit; //nr of units found in the selected fooditem
    private UnitList unitlist;
    private String[] unit_description;
    static int absolute_max_nr_of_unit = 5;

    
    // the user will be able to add floating point numbers as amounts.
    // the integer part (before the decimal point) will be stored in enteredstring which is inherited from MyCanvas
    // the decimal part of the amount that the user entered will be sotredin decimals
    char[] decimals;
    // maximum amount of digits in the decimal part
    public static final int decimalslength = 2;
    // maximum amount of digits in the integer part
    public static final int intpartlength = 3;
    // current length of the decimal part
    int deccurlength;
    // if true then cursor blinks on the integral part of the float and
    // user's key presses haf affect on the integral part
    // if false applicable for the decimal part'
    boolean crsorleft;
    
    //if true then the paint function will only display the current toals
    //if false then the paint function will also show cursor ets.
    // also used in keypressed, keypressed has no effect if totalsonly=true
    boolean totalsonly;
    
    //id of the record in selitemrs to be changed, if 0 means an item is added, if > 0 means an item is being changed
    int rec_to_change;
    
    
    //used in keypressed
    char[] digits = {'0','1','2','3','4','5','6','7','8','9'};

    // commands used
    private Command Terug;
    private Command VoegToe;
    private Command Opslaan;
    private Command AndereEenheid;//added 05/11 to support more units
    private Command CalcPercentage;//added 15/06 to calculate percentage in separate screen
    
    // if true then it means full text doesn't fit on screen, scrolling is necessary'
    boolean scroll;
    //offset is only used in case scroll is true. I defines the amount of scrolling
    //if it's not zero then it will be a negative number.'
    int offset;
    // if true then it means all text fitted on the screen
    boolean reachedend;
    //used paintstring
    boolean tmp;
    int y1;//used for scrolling measurement, y1 will be the coördinate where scrollbar starts

    static private int scrollbarwidth = 5;
    
    // added on 2/11/2008 to support multiple units
    //static public int max_nr_of_units = 3;
    
    //all used in paint
    Float ins;
    String instime;
    Date today;
    Calendar cal;
    int barhght;
    private Command ok;
    private CommandListener cmdlistner;
    private String str_chose_or_modify_amnt;
    

    /** Creates a new instance of AddItem */
    public AddItem(Font userfont, HelpDiabetes midlet) {
        super(userfont,midlet);
        decimals = new char[decimalslength];
        kcal = new Float();
        // same principle apply for eiwit, koolh and vet
        eiwit = new Float();
        koolh = new Float();
        vet = new Float();
        totkoolh = new Float();
        toteiwit = new Float();
        totvet = new Float();
        totkcal = new Float();
        total = new Float();
        unitlist = new UnitList();
        unit_description = new String[absolute_max_nr_of_unit];
        
        scroll = false;//we start with this assumption, if needed scroll will be set to true and repaint will occur
        offset  = 0;
        
        //the commands
        Terug = new Command(str_terug[HelpDiabetes.languageIndex],Command.EXIT,1);
        this.addCommand(Terug);
        VoegToe = new Command(str_voegtoe[HelpDiabetes.languageIndex],Command.OK,2);
        //command will be added in ItemSelected() and removed in ShowTotal()
        Opslaan = new Command(str_opslaan[HelpDiabetes.languageIndex],Command.OK,2);
        //command will be added in ItemSelected() and removed in ShowTotal()
        this.setCommandListener(this);
        //command added to support multiple units. Will be added only in case multiple units are supported, and removed otherwise
        AndereEenheid = new Command(str_andere_eenheid[HelpDiabetes.languageIndex],Command.SCREEN,3);
        //added 15/06 to support calculation of percentage in separate screen
        CalcPercentage = new Command(str_calc_percentage[HelpDiabetes.languageIndex],str_calc_percentagelong[HelpDiabetes.languageIndex],Command.SCREEN,3);
        
    }

    public void paint(Graphics graphics) {
        x=0;y=0;
        //first set the font to the one passed to the constructor of GetItemFromUser
        graphics.setFont(userfont);

        //clear the screen 
        graphics.setColor(255,255,255);
        graphics.fillRect(0, 0, scrwidth, scrhght);
              
        
        if (totalsonly) {//this means the user selected option 'show total'
            koolh =  new Float();
            eiwit =  new Float();
            kcal =  new Float();
            vet =  new Float();
            
        } else {
                //following piece of code I added because I had some problem with N73 when chosing an item from list when searching for an item
                //it appeared that sometimes , b still had the last value it had in deepsearch.paint(),
                try {
                    if (chosenrecordid > 0) {
                        blength = FoodFile.getRecord(chosenrecordid,b,0);
                    }
                }  catch (RecordStoreNotOpenException ex) {
                    (new ReportException()).Report("RecordStoreNotOpenException in AddItem.paint()",ex,false);
                } catch (InvalidRecordIDException ex) {
                    (new ReportException()).Report("InvalidRecordIDException in AddItem.paint()",ex,false);
                } catch (RecordStoreException ex) {
                    (new ReportException()).Report("RecordStoreException inAddItem.paint()",ex,false);
                }
                paintstring(b,blength,false,graphics,userfont,true);
                x=0;y= y+fonthght;

                paintstring((new Integer(std_amnt)).toString().getBytes(),false,graphics,userfont);
                
                //changed 23/06 - added splitting of unit, based on presence of '=', request C.J.
                if (units[unit].indexOf("=") > -1) {
                    paintstring((" " + units[unit].substring(0,units[unit].indexOf("=")) + " ").getBytes(),false,graphics,userfont,true);
                } else
                    paintstring((" " + units[unit] + " ").getBytes(),false,graphics,userfont,true);

                
                //here I calculate the amount of grams of KH, per unit, if the unit is gram or milliliter then mulitply with 100, rounde to 1 digit after decimal point
                paintstring((" " + str_bevat[HelpDiabetes.languageIndex] + " ").getBytes(),false,graphics,userfont,true);
                x=0;y= y+fonthght;
                paintstring( (  Float.Int(     koolh.Mul(std_amnt).Mul(10).Add(new Float(5,-1))   ).Div(10).toString()
                            + " " + str_amount_kh[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                x=0;y= y+fonthght;
                paintstring(str_chose_or_modify_amnt.getBytes(),false,graphics,userfont,true);
                
                
                x=0;y= y+fonthght;
                // a horizontal line under the enteredstring
                graphics.drawLine(0,y,scrwidth,y);
                x=2;y=y+2;
                if (enteredstring.enteredstringlength > 0) {
                    //paint the integer part
                    paintstring((new String(enteredstring.enteredstring)).getBytes(),false,graphics,userfont);
                } else {
                    // paint '0'
                    paintstring("0".getBytes(),false,graphics,userfont);
                }
                if (crsorleft) {
                    printcursor(graphics);
                    x=x+2;
                }
                // print the decimal character - not using paintstring because this guy won't print comma's'
                graphics.drawChar('.',x, y,Graphics.TOP|Graphics.LEFT);
                x = x + userfont.charWidth('.');
                
                if (deccurlength > 0) {
                    paintstring((new String(decimals)).getBytes(),false,graphics,userfont);
                    if (!crsorleft) {
                        printcursor(graphics);
                        x=x+2;
                    }
                } else {
                    // paint '0'
                    if (!crsorleft) {
                        printcursor(graphics);
                        x=x+2;
                    }
                    paintstring("0".getBytes(),false,graphics,userfont);
                }
                

                x=x+userfont.charWidth(' ');
                if (units[unit].indexOf("=") > -1) {
                    String unitString = units[unit].substring(0,units[unit].indexOf("="));
                    //removing "de" and "d'" as requested by axelle and dominique
                    paintstring((  ((unitString.endsWith("de") || unitString.endsWith("d'")) ? unitString.substring(0, unitString.length() - 2): unitString) + " " +
                            str_bevat[HelpDiabetes.languageIndex] +
                            " ").getBytes(),false,graphics,userfont,true);
                }
                else
                    paintstring((  units[unit] + " " + str_bevat[HelpDiabetes.languageIndex] + " ").getBytes(),false,graphics,userfont,true);
                
                switch (((Integer)HDProperties.get("Kolom")).intValue()) {
                    case 0 :
                        if (!eiwit.isError()) {
                            paintstring(       (((Float.Int(CalcAmount().Mul(eiwit).Mul(10).Add(new Float(5,-1))).Div(10).toString())) + " " + str_amount_ei[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                        }
                        break;
                    case 1 :
                        if (!kcal.isError()) {
                            paintstring(       (((Float.Int(CalcAmount().Mul(kcal).Mul(10).Add(new Float(5,-1))).Div(10).toString())) + " " + str_amount_kcal[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                        }
                        break;
                    case 2 :
                        if (!koolh.isError()) {
                            paintstring(       (((Float.Int(CalcAmount().Mul(koolh).Mul(10).Add(new Float(5,-1))).Div(10).toString())) + " " + str_amount_kh[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                        }
                        break;
                    case 3 :
                        if (!vet.isError()) {
                            paintstring(       (((Float.Int(CalcAmount().Mul(vet).Mul(10).Add(new Float(5,-1))).Div(10).toString())) + " " + str_amount_vet[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                        } 
                        break;
                }
                newline(0);
        }
        
        if (totalsonly) {//we'll also show the amounts of insuline needed'
            //start by checking which value is to be used
            cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.set(Calendar.MONTH, Calendar.JANUARY);
            cal.set( Calendar.DAY_OF_MONTH, 1 );
            cal.set( Calendar.YEAR, 1970 );
            //cal.setTimeZone(TimeZone.getTimeZone("Europe/Brussels"));
            today = cal.getTime();
            //System.out.println(cal.getTime().toString());
            //now we have today set to current time january 1 1970
            if (today.getTime() < ((Long)HDProperties.get("OntbijtTime")).longValue()) {
                //it's before switch time ontbijt to middagmaal
                ins = ((Float)HDProperties.get("Ins_1"));
                instime = str_ontbijt[HelpDiabetes.languageIndex];
            } else if (today.getTime() < ((Long)HDProperties.get("MiddagmaalTime")).longValue()) {
                ins = ((Float)HDProperties.get("Ins_2"));
                instime = str_middagmaal[HelpDiabetes.languageIndex];
            } else if (today.getTime() < ((Long)HDProperties.get("VieruurtjeTime")).longValue()) {
                ins = ((Float)HDProperties.get("Ins_3"));
                instime = str_vieruurtje[HelpDiabetes.languageIndex];
            } else {
                ins = ((Float)HDProperties.get("Ins_4"));
                instime = str_avondmaal[HelpDiabetes.languageIndex];
            }
            
            if (!ins.Equal(Float.ZERO))  {
                //System.out.println(ins);
                if (!koolh.isError()) {
                    paintstring((instime + " ==> " + Float.Int(koolh.Add(totkoolh).Div(ins).Mul(10).Add(new Float(5,-1))).Div(10).toString() + " " + str_unitsins[HelpDiabetes.languageIndex]).getBytes(),false,graphics,userfont,true);
                    newline(0);
                }
            }
        }
        y=y+1;
        paintstring((str_total[HelpDiabetes.languageIndex] + " :").getBytes(),true,graphics,userfont,true);
        newline(0);
        //everything which comes after should be scrollable
        //we first clip the graphics to the region where scrolling may occur
        //this  is because we'll print at y coördinates less than the current y coördinate, so it's to avoid we overwrite previous text because we'll print at y + offset with offset negative value'
        graphics.setClip(x,y,scrwidth,scrhght - y);
        
        //if we're currently scrolling then we'll reduce the scrwidth to allow adding a scrollbar
        if (scroll) {
            scrwidth = scrwidth - scrollbarwidth;
            y1 = y;//we need this for calculating the scrollbarlength
        } 
        //first assumption is that everything will fit on screen
        reachedend = false;

        if (!koolh.isError() & !totkoolh.isError())  {
            reachedend = paintstringwithoffset((Float.Int(CalcAmount().Mul(koolh).Add(totkoolh).Mul(10).Add(new Float(5,-1))).Div(10).toString() + " " + str_amount_kh[HelpDiabetes.languageIndex])     .getBytes(),false,graphics,userfont,true);
            if (!((Float)HDProperties.get("Carbs_Per_Portion")).Equal(Float.ZERO))  {
                reachedend = paintstringwithoffset((" (" +
                        Float.Int(CalcAmount().Mul(koolh).Add(totkoolh).Div((Float)HDProperties.get("Carbs_Per_Portion")).Mul(10).Add(new Float(5,-1))).Div(10).toString()
                        + " "
                        + str_porties_1[HelpDiabetes.languageIndex]
                        + (Float.Int(((Float)HDProperties.get("Carbs_Per_Portion")).Mul(10).Add(new Float(5,-1))).Div(10)).toString()
                        + str_porties_2[HelpDiabetes.languageIndex] +
                        ")")     .getBytes(),false,graphics,userfont,true);
                newline(0);
            }
        }
        if (!eiwit.isError() & !toteiwit.isError())  {
            reachedend = paintstringwithoffset((Float.Int(CalcAmount().Mul(eiwit).Add(toteiwit).Mul(10).Add(new Float(5,-1))).Div(10).toString() + " " + str_amount_ei[HelpDiabetes.languageIndex])     .getBytes(),false,graphics,userfont,true);
            newline(0);
        }
        if (!kcal.isError() & !totkcal.isError())  {
            reachedend = paintstringwithoffset((Float.Int(CalcAmount().Mul(kcal).Add(totkcal).Mul(10).Add(new Float(5,-1))).Div(10).toString() + " " + str_amount_kcal[HelpDiabetes.languageIndex])     .getBytes(),false,graphics,userfont,true);
            newline(0);
        }
        if (!vet.isError() & !totvet.isError())  {
            reachedend = paintstringwithoffset((Float.Int(CalcAmount().Mul(vet).Add(totvet).Mul(10).Add(new Float(5,-1))).Div(10).toString() + " " + str_amount_vet[HelpDiabetes.languageIndex])     .getBytes(),false,graphics,userfont,true);
        }

        
        if (scroll) {
            // if we're already scrolling at this point, we'll start by showing the scrollbar'
            //first the long vertical line
            graphics.drawLine(scrwidth + 1,y1,scrwidth + 1,scrhght);
            //divide total length of scrollbar by three
            barhght = (scrhght - y1)/3;
            if (offset == 0) {//first part of scrollable text is shown, show first part of bar
                graphics.fillRect(scrwidth+2,y1,scrollbarwidth,barhght);
            } else if (reachedend) {//last part of scrollable text , show last part of bar
                graphics.fillRect(scrwidth+2,scrhght - barhght,scrollbarwidth,barhght);
            } else {//middle part to be shown
                graphics.fillRect(scrwidth+2,y1 + barhght,scrollbarwidth,barhght);
            }
        }
        if (!reachedend) {//it doens't fit on the screen'
           scroll = true;
        }
        
        //reset the screensize to it's real values
        scrwidth = midlet.getDisplay().getCurrent().getWidth();
        //remove the clipping
        graphics.setClip(0, 0, scrwidth, scrhght);


    }

    public void commandAction(Command command, Displayable displayable) {
        resetexittimer(this);
        if ((command == VoegToe) | (command == Opslaan)){
            addItemToList(chosenrecordid,CalcAmount(),unit_number_to_add,rec_to_change);
            //switch back to getitemfromuser - don't switch back to curdisp because curdisp may be DeepSearch' - it's better to switch hback immediately to getitemfromuser'
            midlet.getDisplay().setCurrent(HelpDiabetes.getitemfromuser);
        } else if (command == AndereEenheid){
            unitlist.SelectUnit(this,max_nr_of_unit,unit_description);
        } else if (command == CalcPercentage) {
                            Float percentage = new Float(0);
                            if (total.Equal(percentage)) {
                            } else
                                percentage = Float.Int(totkoolh.Div(total).Mul(1000).Add(new Float(5,-1))).Div(10);
        	                Alert warning = new Alert(
                                str_warning_title[HelpDiabetes.languageIndex],//alert title
                                str_warning1[HelpDiabetes.languageIndex] +
                                "\n\n" +
                                str_warning2[HelpDiabetes.languageIndex] +
                                " " +
                                percentage.toString() +
                                " % " +
                                str_of_carbs[HelpDiabetes.languageIndex],//the text to be displayed
                                null,
                                AlertType.WARNING);
                            warning.setTimeout(Alert.FOREVER);
                            ok = new Command(str_ok[HelpDiabetes.languageIndex],Command.OK,0);
                            warning.addCommand(ok);
                            cmdlistner = new CommandListener() {
                                public void commandAction(Command command, Displayable displayable) {
                                	// no matter what command, return to previous screen
                                        HelpDiabetes.midlet.getDisplay().setCurrent(HelpDiabetes.getitemfromuser.additem);
                                }
                            };
                            HelpDiabetes.midlet.getDisplay().setCurrent(warning);
       } else {
            midlet.getDisplay().setCurrent(curdisp);
        }
        resetflipfloptimer(curdisp);
    }
    
    public synchronized void keyPressed (int keyCode) {
        resetexittimer(this);
      
        //first check up and down, if not up or down, then we need to check if this is being called for totalsonly
        if (keyCode != -15000) {
            if (      (keyCode < KEY_NUM0) || (keyCode > KEY_NUM9)       ) {//if this check is not done then this piece of code would be executed when pressing '2' or '8' 
              if (getGameAction(keyCode) == UP) {
                   if (offset < 0) {
                        offset = offset + fonthght;
                    }
               } else if (getGameAction(keyCode) ==  DOWN) {
                    if (scroll & !reachedend) {
                        offset = offset - fonthght;
                    }
                }
            }
        }
           
        //we don't need the rest if this displayable is showing totals only    
        if (totalsonly) return;
        
        cancelflipfloptimer();
        //first check for num values, this has highest priority
        //then for gameactions
        //then back or clearkey
        // digit was pressed
            //checking on value -15000 first because otherwise a call woud be method to getgameaction(-15000) which gave an exception with the emulator
            if (keyCode == -15000) {//-15000 ued for a trick, see comment a bit further
                        movebackthecursor();
                }         
            else if (        (keyCode > (KEY_NUM0 -1)) && (keyCode < (KEY_NUM9 + 1))       ) {
                if (crsorleft) {
                    // try to add a digit on the integer part
                    if (enteredstring.enteredstringlength < intpartlength) {
                        // we can still add something
                        //if enteredstring.enteredstring = "0" then I'll remove it and reset the length to 0'
                        if (enteredstring.enteredstringlength == 1 & enteredstring.enteredstring[0] == '0') {
                            enteredstring.enteredstring[0]=digits[keyCode - KEY_NUM0];
                        } else {
                            enteredstring.enteredstring[enteredstring.enteredstringlength] = digits[keyCode - KEY_NUM0];
                            enteredstring.enteredstringlength++;
                        }
                    } // else we do nothing
                } else {
                    // try to the decimal part
                    if (deccurlength < decimalslength) {
                        // we still can add something
                        decimals[deccurlength] = digits[keyCode - KEY_NUM0];
                        deccurlength++;
                    } // else we do nothing
                }
            } else
            if (getGameAction(keyCode) == LEFT) {
                    if (!crsorleft) {
                        if (deccurlength > 0) {
                            //here we'll use the LEFT key to remove a character, and not to jump the cursor to the right part'
                            // so I recall keypressed with -15000, which is my own keycode to force a back key
                            keyPressed(-15000);
                            //now if there's no more digits on the right side we'll also jump the cursor to the left side'
                            if (deccurlength  == 0) {
                                crsorleft = true;
                            }
                        } else {
                            crsorleft = true;
                        }
                    } else {//cursor is on the left side
                        if (enteredstring.enteredstringlength > 0) {
                            //here we'll use the LEFT key to remove a character, and not to jump the cursor to the right part'
                            // so I recall keypressed with -15000, which is my own keycode to force a back key
                            keyPressed(-15000);
                        } else {
                            crsorleft =true;
                        }    
                    }
            } else if (getGameAction(keyCode) == RIGHT) {
                    if (crsorleft) {
                          crsorleft = false;
                    }
             //switch back to getitemfromuser - don't switch back to curdisp because curdisp may be DeepSearch' - it's better to switch hback immediately to getitemfromuser'
            } else if (getGameAction(keyCode) == FIRE) {

                 addItemToList(chosenrecordid,CalcAmount(),unit_number_to_add,rec_to_change);
                 //switch back to getitemfromuser - don't switch back to curdisp because curdisp may be DeepSearch' - it's better to switch hback immediately to getitemfromuser'
                 midlet.getDisplay().setCurrent(HelpDiabetes.getitemfromuser);
            } else if (keyCode == BACK_KEY | keyCode == CLEAR_KEY | keyCode == -15000) {//-15000 ued for a trick, see comment a bit further
                        movebackthecursor();
                } 
        if (keyCode != -15000) {
            flipflopthecursor();
        }
    }
    
    //just a method because it's a piece of code that I need twice'
    void movebackthecursor() {
        if (crsorleft) {
            if (enteredstring.enteredstringlength > 0) {
                enteredstring.enteredstringlength--;
                enteredstring.enteredstring[enteredstring.enteredstringlength] = ',';
            }
        } else {
            if (deccurlength > 0) {
                deccurlength--;
                decimals[deccurlength] = ',';
            } // else we do nothing
        }
        return;
    }
    
    // here's the method that will be called by an instance of getitemfrom user when user has selected an item, or an instance of ReadItemList
    // The recid will point the the food element in foodrs
    // unit is the unit - if unit = 0 then it means the method is called for adding a new item, not for changing an existing item
    // oldamount is the the amount of units in the selected record, only applicable in case called for changing an existing item - it's in string formatted float'
    // unitnumber has been added on 2/11/2008. It's used for multiple units per item. It can be 1, 2 or 3'
    // selitemrs_recid points to the record in selitemsrs to be changed -  actually it's a bit redundant info because it's possible to deducate unit&oldamount from selitemrs_recid'
    // NOTE 2/11/2008  : In practice unit is always '8'. 
    
    //two variants added on 10/11/2008
    // one variant that stores the curdisp and calls the other variant, this one is used by UnitList.SelectUnit
    public void ItemSelected (int foodrs_recid, int unit, String oldamount, int selitemrs_recid, int unitnumber) {
        curdisp = midlet.getDisplay().getCurrent();
        ItemSelectedWithoutStoringCurdisp(foodrs_recid,unit,oldamount,selitemrs_recid,unitnumber);
    }
    // the other variant which is the real method itemselected, 
    public void ItemSelectedWithoutStoringCurdisp (int foodrs_recid, int unit, String oldamount, int selitemrs_recid, int unitnumber) {
        int i2;
        int i1;
        Float amount1;
        amount1 = Float.parse(oldamount,10);
        
        //unit_number_to_add needs to get initial value = unitnumber. It may be changed afterwards if user selects other unit.
        // that value will then be used when user add's or save's fooditem selection'
        unit_number_to_add  = unitnumber;
            
        try {
            if (unit == 0) {// means the method is called to add a new element.
                this.addCommand(VoegToe);
                this.removeCommand(Opslaan);
                str_chose_or_modify_amnt = str_choseamnt[HelpDiabetes.languageIndex];
                //we start with 
            } else {
                this.addCommand(Opslaan);
                this.removeCommand(VoegToe);
                str_chose_or_modify_amnt = str_modifyamnt[HelpDiabetes.languageIndex];
            }
            
            //added 15/06
            this.removeCommand(CalcPercentage);
        
            midlet.getDisplay().setCurrent(this);
            resetflipfloptimer(this);
            //setscrsize();
            totalsonly = false;
            
            // calculate toteiwit, totkcal, totkoolh, totvet
            CalcItemsFromList();
            
            chosenrecordid = foodrs_recid;
            blength = FoodFile.getRecord(foodrs_recid,b,0);
            
            //added 4/11 to support multiple units
            // count number of units in the selected food item
            //if the selected item contains multiple units, then we'll add the command which allows to select the unit'
            max_nr_of_unit = 1;
            i1 = getfirstsemicolon();
            i2 = getnextsemicolon();
            if (i2 > i1 + 1) {
                unit_description[0] = new String(b,i1+1,i2-i1-1);
                i1=i2;
                i2=getnextsemicolon();
                unit_description[0] = new String(b,i1+1,i2-i1-1) + " " + unit_description[0];
            } else
            {
                i1=i2;
                i2=getnextsemicolon();
                unit_description[0] = "1 " + str_stuk[HelpDiabetes.languageIndex] ;
            }
            i1 = getnextsemicolon();i1 = getnextsemicolon();i1 = getnextsemicolon();i1 = getnextsemicolon();
            try { // aim is to continue as long as there's no exception. If an exceptio occurs it means there's no furtehr unit'
                //if the foodfile is an old version then it contains only  7 columns or 6 comma's, so i1 = -1
                //we'll check for that and throw an exception if so in order to get out of this try block
                if (i1 == -1) throw new Exception();
                i2 =  getnextsemicolon();
                while (max_nr_of_unit < (absolute_max_nr_of_unit +1)) {
                    if (i2 > i1 + 1) {//trying to read the unit description although it could be that the end of the line is already passed
                       unit_description[max_nr_of_unit]= new String(b,i1+1,i2-i1-1);
                       i1=i2;
                       i2=getnextsemicolon();
                       unit_description[max_nr_of_unit]= new String(b,i1+1,i2-i1-1) + " " + unit_description[max_nr_of_unit];
                    } else
                    {
                       i1=i2;
                       i2=getnextsemicolon();
                        unit_description[max_nr_of_unit] = "1 " + str_stuk[HelpDiabetes.languageIndex];
                    }
                    max_nr_of_unit = max_nr_of_unit + 1;
                    if (i1 == -1 || i2 == -1) {
                        max_nr_of_unit = max_nr_of_unit - 1;
                        throw new Exception();
                    }
                    i1 = getnextsemicolon();
                    if (i1 == -1 || i2 == -1) {
                        max_nr_of_unit = max_nr_of_unit - 1;
                        throw new Exception();
                    }
                    i1 = getnextsemicolon();
                    if (i1 == -1 || i2 == -1) {
                        max_nr_of_unit = max_nr_of_unit - 1;
                        throw new Exception();
                    }
                    i2 = getnextsemicolon();
                    if (i1 == -1 || i2 == -1) {
                        max_nr_of_unit = max_nr_of_unit - 1;
                        throw new Exception();
                    }
                    if (i2 > i1 + 1) {
                    } else {
                        //there's no amount filled in
                        max_nr_of_unit = max_nr_of_unit - 1;
                        throw new Exception();
                    }
                    // there was a unit2
                    i1 = getnextsemicolon();
                    i2 = getnextsemicolon();
                }
            } catch (Exception e) {
                
            }
            if (max_nr_of_unit > 1) {
                this.addCommand(AndereEenheid);
            } else {
                this.removeCommand(AndereEenheid);
            }
                    
            
            
            //kcal, eiwit, vet, and koolh will be set to amounts corresponding to contents of b
           int returnvalue = CalculateAmounts_in_b(unitnumber);
             
            // this I do because i want to call paintstring(byte[],boolean,graphics) with entredstring.enteredstring
            // but only the entered digits should be printed, so as user adds or removes digits, ',' will be added or removed (see keypressed)
            int i;
            for (i = 0 ; i<enteredstring.enteredstring.length;i++) {
                enteredstring.enteredstring[i] =',';
            }
            for (i = 0;i<decimals.length;i++) {
                decimals[i] = ',';
            }
            //following settings assume method is called for adding a new item
            deccurlength = 0;
            enteredstring.enteredstringlength=0;
                char[] strval = amount1.toString().toCharArray();
                for (i = 0;i < strval.length;i++) {
                    if (strval[i] == '.') {
                        break;
                    }
                    enteredstring.enteredstring[i] = strval[i];
                    enteredstring.enteredstringlength = i+1;
                }
                i++;
                for (;i < strval.length;i++) {
                    decimals[i - (enteredstring.enteredstringlength + 1)] = strval[i];
                    deccurlength = i - enteredstring.enteredstringlength;
                    if ((deccurlength == 1) & (decimals[0] == '0')) {
                        deccurlength = 0;
                        decimals[0] = ',';
                    }
                }


            rec_to_change = 0;
            
            //if method is called for changing an existing record, then the totals need to be recalculated
            if (unit > 0) {
                toteiwit = toteiwit.Sub(eiwit.Mul(amount1));
                totkcal = totkcal.Sub(kcal.Mul(amount1));
                totkoolh = totkoolh.Sub(koolh.Mul(amount1));
                totvet = totvet.Sub(vet.Mul(amount1));
                //added for Christophe 25/05/2009
                total = total.Sub(amount1);
                //record id of the selected item to change must be stored because used when command 'Opslaan' is selected
                rec_to_change = selitemrs_recid ;
            }
            
            
            crsorleft = true;
            scroll = false;//we start with this assumption, if needed scroll will be set to true and repaint will occur
            offset = 0;
            //we're ready to print the stuff and let the user chose how much he wants'
            repaint();

            //request from Ax, to open unit screen immediately after having selected an item.
            if (max_nr_of_unit > 1 && unit == 0)
                commandAction(AndereEenheid, this);
              
        } catch(NumberFormatException nex) {
            midlet.getDisplay().setCurrent(curdisp);
            (new UserInfo()).Report("Error\n\n" 
                    + "This item is not correctly formatted.\n"
                    + "Check the excel food table in row " + chosenrecordid);
        } catch (Exception ex) {
            midlet.getDisplay().setCurrent(curdisp);//setting back to getitemfrom user, report exception will immediately set it's own displayable and switch back to getitem from user after user pressed ok'
            (new ReportException()).Report("Exception in AddItem.ItemSelected while processing record " + foodrs_recid,ex,false);
        }
    }
    
    // this method will return enteredstring into a float value
    Float CalcAmount() {
        return Float.parse(
        ((enteredstring.enteredstringlength > 0) 
            ? (new String(enteredstring.enteredstring,0,enteredstring.enteredstringlength))
            : (new String("0")) )
            +
         "."
            +
         ((deccurlength > 0)
            ? (new String(decimals,0,deccurlength))
            : (new String("0") ))
        ,10 );
    }
    
    
   //adds an item with foodfile record id, amount and unit to the list selitemsrs
   // recid = id of the record in foodrs which contains the added item
   // amount = amount chosen by user
    // unitnumber = added on 2/11/2008 to allow multiple units per food item
   // rec_to_change : if > 0 then it's an existing record in selitemsrs that needs to be changed'
   void addItemToList (int recid, Float amount, int unitnumber, int rec_to_change) {
       byte [] oldb;
       try {
           //first check if recordstore with selected items is already opened
           if (HelpDiabetes.selitemsrs == null) {
                    //recordstore is not yet opened, not to check first if recordstore exists

                    HelpDiabetes.selitemsrs = RecordStore.openRecordStore("selecteditems",true);

           }
           oldb = (Integer.toString(recid) + "," + amount.toString() + "," + Integer.toString(unitnumber)).getBytes();
           if (rec_to_change == 0) {
                HelpDiabetes.selitemsrs.addRecord(oldb,0,oldb.length);
           } else {
               HelpDiabetes.selitemsrs.setRecord(rec_to_change,oldb,0,oldb.length);
           }
           HelpDiabetes.getitemfromuser.emptyenteredstring();
        }  catch (Exception ex2) {
            (new ReportException()).Report("Exception in AddItem.addItemToList",ex2,true);
        }
   }
   
   //opens the selecteditemsrs , reads all items in it and calculates the current total of kcal, koolh, vet, eiwit and writes the sum into toteiwit, totkcal, totkh, totvet
   //added 10/06 also calculation of total
   public int CalcItemsFromList() {
       int unitnumber;
       int returnvalue = 0;
       int recid1;
       Float amount1;
       int i1,i2;
       RecordEnumeration enumer = null;
       totkcal = new Float();
       totkoolh = new Float();
       totvet = new Float();
       toteiwit = new Float();
       total = new Float();
       try {
           if (HelpDiabetes.selitemsrs == null) {
                    //recordstore is not yet opened, not to check first if recordstore exists
                    HelpDiabetes.selitemsrs = RecordStore.openRecordStore("selecteditems",false);
           }
           enumer = HelpDiabetes.selitemsrs.enumerateRecords(null,null,false);
           while (enumer.hasNextElement()) {
               b = enumer.nextRecord();
               blength = b.length;
               // first get recid, and amount
               i1 = getfirstsemicolon();
               try {//added 10 june 2009 to support own food element, if record starts with text then
                   //next statement will throw exception which will be caught and handled
                   recid1 = Integer.parseInt(new String(b,0,i1));
                   i2 = getnextsemicolon();
                   amount1 = Float.parse(new String(b,i1+1,i2-i1-1),10);
                   // now get the unitnumber
                   i1 = i2;
                   i2 = b.length;
                   unitnumber = Integer.parseInt(new String(b,i1+1,i2-i1-1),10);

                   b = new byte[maxblength];
                   blength = FoodFile.getRecord(recid1,b,0);
                   CalculateAmounts_in_b(unitnumber);
                   toteiwit = toteiwit.Add(eiwit.Mul(amount1));
                   totkcal = totkcal.Add(kcal.Mul(amount1));
                   totkoolh = totkoolh.Add(koolh.Mul(amount1));
                   totvet = totvet.Add(vet.Mul(amount1));
                   total = total.Add(weight_of_one_unit.Mul(amount1));
               } catch (NumberFormatException nrforex) {
                   //don't need the name of the fooditem so jump directly to next
                   i2 = getnextsemicolon();
                   int perc = Integer.parseInt(new String(b,i1+1,i2-i1-1));
                   i1 = i2;
                   i2 = b.length;
                   int amnt = Integer.parseInt(new String(b,i1+1,i2-i1-1));
                   //eiwit, kcal, vet can be set to invalid value because the own food item feature doesn't allow to enter this
                   toteiwit = new Float(Float.ERROR);
                   totkcal = new Float(Float.ERROR);
                   totvet = new Float(Float.ERROR);
                   //koolh should be calcualted
                   totkoolh = totkoolh.Add(new Float((long)amnt).Mul(perc).Div(100));
                   total = total.Add(new Float(amnt));
                   b = new byte[maxblength];

               }
           }
       } catch (RecordStoreNotFoundException ex1) {
            ;//recordstore doesn't exist, so there's nothing to calculate, so do nothing, finally block will be called where 0 will be returned'
       } catch (Exception ex2) {
            (new ReportException()).Report("Exception in CalcItemsFromList",ex2,true);
       } finally {
            if( enumer != null) {
                enumer.destroy();
                enumer = null;
            }
            return returnvalue;
       }
   }
   
   
   //will be called to show current totals
   public void showtotal() {
        this.removeCommand(VoegToe);
        this.removeCommand(Opslaan);
        this.removeCommand(AndereEenheid);
        //added 15/06 to put the percentage calculation of carbs in a seprate screen
        this.addCommand(CalcPercentage);
        curdisp = midlet.getDisplay().getCurrent();
        midlet.getDisplay().setCurrent(this);
        //setscrsize();
        totalsonly = true;
        
        // calculate current total amounts of koolh, vet, eiwit, kcal
        CalcItemsFromList();
        
        scroll = false;//we start with this assumption, if needed scroll will be set to true and repaint will occur
        offset = 0;
        repaint();
   }
   
   // this method will first reset y to y + offset
   // then call super.paintstring(byte[] toprint,boolean invert,Graphics graphics,Font thefont)
   // then reset y to y - offset
   boolean paintstringwithoffset( byte[] toprint,boolean invert,Graphics graphics,Font thefont,boolean wrap){
       y = y + offset;
       tmp =  super.paintstring(toprint,invert,graphics,thefont,wrap);
       y = y - offset;
       return tmp;
   }
   
   //returns the unit_number_to-add
   public int get_unit_nubmer_to_add() {
       return unit_number_to_add;
   }
   
   //returns the rec-to-chnage
   public int get_rec_to_change() {
       return rec_to_change;
   }
   
   //returns the chosen_rec_id
   public int get_chosen_record_id() {
       return chosenrecordid;
   }

   String GetClassName() {
        return("AddItem");
   }

}
